# -*- coding: utf-8 -*-
"""
@ Created on 2024-06-14 12:23
---------
@summary: 服务器初始化
---------
@author: Lsaiah
"""

from fastapi import FastAPI, HTTPException
from fastapi.middleware.cors import CORSMiddleware
from fastapi.middleware.trustedhost import TrustedHostMiddleware
from fastapi.middleware.gzip import GZipMiddleware
from fastapi.staticfiles import StaticFiles
from fastapi.exceptions import RequestValidationError
from jose import JWTError

import fastapi_cdn_host
import os
from settings import settings
from log import logger
from db import init_db, close_db
from core.exceptions import CustomHTTPException, AuthenticationException, AuthorizationException
from core.exception_handler import (
    custom_http_exception_handler,
    authentication_exception_handler,
    authorization_exception_handler,
    validation_exception_handler,
    jwt_exception_handler,
    http_exception_handler,
    general_exception_handler
)


class InitializeApp:
    """FastAPI应用初始化类"""

    def __init__(self):
        self.app = FastAPI(
            title="FastAPI Vue3 Admin",
            description="基于FastAPI和Vue3的后台管理系统",
            version="1.0.0",
            docs_url="/docs",
            redoc_url="/redoc",
            openapi_url="/openapi.json"
        )
        
        fastapi_cdn_host.patch_docs(self.app)
        self._setup_middleware()
        self._setup_exception_handlers()
        self._setup_events()
        self._setup_routes()

    def _setup_middleware(self):
        """设置中间件"""
        # CORS中间件
        self.app.add_middleware(
            CORSMiddleware,
            allow_origins=["*"],  # 生产环境应该设置具体的域名
            allow_credentials=True,
            allow_methods=["*"],
            allow_headers=["*"],
        )

        # 可信主机中间件
        self.app.add_middleware(
            TrustedHostMiddleware,
            allowed_hosts=["*"]  # 生产环境应该设置具体的域名
        )

        # Gzip压缩中间件
        self.app.add_middleware(GZipMiddleware, minimum_size=1000)

    def _setup_exception_handlers(self):
        """设置异常处理器"""
        # 自定义HTTP异常处理器
        self.app.add_exception_handler(CustomHTTPException, custom_http_exception_handler)
        
        # 认证异常处理器
        self.app.add_exception_handler(AuthenticationException, authentication_exception_handler)
        
        # 授权异常处理器
        self.app.add_exception_handler(AuthorizationException, authorization_exception_handler)
        
        # 请求验证异常处理器
        self.app.add_exception_handler(RequestValidationError, validation_exception_handler)
        
        # JWT异常处理器
        self.app.add_exception_handler(JWTError, jwt_exception_handler)
        
        # HTTP异常处理器
        self.app.add_exception_handler(HTTPException, http_exception_handler)
        
        # 通用异常处理器
        self.app.add_exception_handler(Exception, general_exception_handler)

    def _setup_events(self):
        """设置事件处理器"""
        @self.app.on_event("startup")
        async def startup_event():
            """应用启动事件"""
            logger.info("应用启动中...")
            try:
                # 初始化数据库
                await init_db()
                logger.info("数据库初始化成功")
                
                # 创建静态文件目录
                if not os.path.exists("static"):
                    os.makedirs("static")
                
                logger.info("应用启动成功")
            except Exception as e:
                logger.error(f"应用启动失败: {str(e)}")
                raise

        @self.app.on_event("shutdown")
        async def shutdown_event():
            """应用关闭事件"""
            logger.info("应用关闭中...")
            try:
                # 关闭数据库连接
                await close_db()
                logger.info("数据库连接已关闭")
                logger.info("应用关闭成功")
            except Exception as e:
                logger.error(f"应用关闭失败: {str(e)}")

    def _setup_routes(self):
        """设置路由"""
        # 健康检查
        @self.app.get("/health")
        async def health_check():
            """健康检查接口"""
            return {
                "status": "healthy",
                "message": "服务运行正常",
                "timestamp": "2024-01-01T00:00:00Z"
            }

        # 根路径
        @self.app.get("/")
        async def root():
            """根路径"""
            return {
                "message": "Welcome to FastAPI Vue3 Admin",
                "version": "1.0.0",
                "docs": "/docs"
            }

        # 静态文件服务
        try:
            self.app.mount("/static", StaticFiles(directory="static"), name="static")
        except Exception as e:
            logger.warning(f"静态文件服务设置失败: {str(e)}")

    def include_router(self, router, **kwargs):
        """包含路由"""
        self.app.include_router(router, **kwargs)

    def get_app(self):
        """获取FastAPI应用实例"""
        return self.app
